package com.audaque.springboot.foshanupload.core.util;

import org.joda.time.DateTime;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zgb
 * @desc ...
 * @date 2023-03-02 10:37:11
 */
public class DateUtilsExtJodaExt {


    /**
     * 获取当前日期时间戳
     *
     * @return
     */
    public static Long getNowTimestamp() {
        return getNowDateTime().getTime();
    }

    /**
     * 获取指定日期时间戳
     *
     * @return
     */
    public static Long getDateTimestamp(Date date) {
        return DateUtilsExtJoda.getDate(date).getTime();
    }


    /**
     * 获取当前日期(yyyy-MM-dd)
     *
     * @return
     */
    public static Date getNowDateTime() {
        return DateUtilsExtJoda.getDate(new Date());
    }




    /**
     * 比较两日期大小
     *
     * @param date      日期
     * @param otherDate 另一个日期
     * @return 比较两日期大小。如果date>otherDate则返回true,否则false
     */
    public static Boolean whenGT(Date date, Date otherDate) {
        Boolean flag = false;
        Date dateTmp = DateUtilsExtJoda.getDateTime(date);
        Date otherDateTmp = DateUtilsExtJoda.getDateTime(otherDate);
        if (dateTmp != null && otherDateTmp != null) {
            long time = dateTmp.getTime() - otherDateTmp.getTime();
            if (time > 0) {
                flag = true;
            }
        }
        return flag;
    }


    /**
     * 比较两日期是否相等
     *
     * @param date      日期
     * @param otherDate 另一个日期
     * @return 比较两日期大小。如果date==otherDate则返回true,否则false
     */
    public static Boolean whenEQ(Date date, Date otherDate) {
        Boolean flag = false;
        Date dateTmp = DateUtilsExtJoda.getDateTime(date);
        Date otherDateTmp = DateUtilsExtJoda.getDateTime(otherDate);
        if (dateTmp != null && otherDateTmp != null) {
            long time = dateTmp.getTime() - otherDateTmp.getTime();
            if (time == 0) {
                flag = true;
            }
        }
        return flag;
    }



    /**
     * 比较两日期是否在同一天
     *
     * @param date      日期
     * @param otherDate 另一个日期
     * @return 比较两日期大小。如果date==otherDate则返回true,否则false
     */
    public static Boolean whenEQDay(Date date, Date otherDate) {
        Boolean flag = false;
        Date dateTmp = DateUtilsExtJoda.getDate(date);
        Date otherDateTmp = DateUtilsExtJoda.getDate(otherDate);
        if (dateTmp != null && otherDateTmp != null) {
            long time = dateTmp.getTime() - otherDateTmp.getTime();
            if (time == 0) {
                flag = true;
            }
        }
        return flag;
    }


    /**
     * 获取日期是一周中的第几天 每周从周一开始
     *
     * @param date
     * @return
     */
    public static int getDateInWeekFewDay(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("E");
        String key = sdf.format(DateUtilsExtJoda.getDateFormat(date, DateFormatUtil.DATE_DEFAULT_FORMAT));
        if ("星期一".equals(key) || "Mon".equals(key) || "MON".equals(key)) {
            return 1;
        } else if ("星期二".equals(key) || "Tue".equals(key) || "TUE".equals(key)) {
            return 2;
        } else if ("星期三".equals(key) || "Wed".equals(key) || "WED".equals(key)) {
            return 3;
        } else if ("星期四".equals(key) || "Thu".equals(key) || "THU".equals(key)) {
            return 4;
        } else if ("星期五".equals(key) || "Fri".equals(key) || "FRI".equals(key)) {
            return 5;
        } else if ("星期六".equals(key) || "Sat".equals(key) || "SAT".equals(key)) {
            return 6;
        }
        return 7;
    }


    /**
     * 计算得到日期区间的所有日期
     * 例如：from=2017-06-25 to=2017-06-28 那么他们之间的日期就是 2017-06-26 2017-06-27
     *
     * @param from
     * @param to
     * @return
     */
    public static List<Date> computeDateRangeDate(Date from, Date to) {
        List<Date> dateRange = new ArrayList<Date>();
        from = DateUtilsExtJoda.getDateFormat(from, DateFormatUtil.DATE_DEFAULT_FORMAT);
        to = DateUtilsExtJoda.getDateFormat(to, DateFormatUtil.DATE_DEFAULT_FORMAT);
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(DateUtilsExtJoda.getDateFormat(from, DateFormatUtil.DATE_DEFAULT_FORMAT));
        startCal.add(Calendar.DAY_OF_YEAR, 1);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(DateUtilsExtJoda.getDateFormat(to, DateFormatUtil.DATE_DEFAULT_FORMAT));
        while (startCal.before(endCal)) {
            dateRange.add(startCal.getTime());
            startCal.add(Calendar.DAY_OF_YEAR, 1);
        }
        return dateRange;
    }


    /**
     * 计算某月一号和最后一天
     *
     * @param sourceDate    源日期
     * @param monthInterval 目标月与当前月月差值（正负均可）
     * @return
     */
    public static Date[] computeMonthFirstAndLastDay(Date sourceDate, int monthInterval) {
        Date[] destDates = new Date[2];
        Calendar cal = Calendar.getInstance();
        cal.setTime(sourceDate);
        cal.add(Calendar.MONTH, monthInterval);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        destDates[0] = DateUtilsExtJodaT.getDate(DateFormatUtil.DATE_FORMATTER.get().format(cal.getTime()));
        if (monthInterval < 0) {
            cal.setTime(sourceDate);
            if (monthInterval < -1) {
                cal.add(Calendar.MONTH, monthInterval + 1);
            }
        }
        if (monthInterval >= 0) {
            cal.add(Calendar.MONTH, 1);
        }
        cal.set(Calendar.DAY_OF_MONTH, 0);
        destDates[1] = DateUtilsExtJodaT.getDate(DateFormatUtil.DATE_FORMATTER.get().format(cal.getTime()));

        return destDates;
    }


    /**
     * 获取当前日期的下一天
     *
     * @return
     */
    public static String getAfterDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, 1);//把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime();   //这个时间就是日期往后推一天的结果
        return DateUtilsExtJoda.getDateToString(date);
    }

    /**
     * 获取当前日期的前一天
     *
     * @return
     */
    public static String getBeforeDay(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);//把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime();   //这个时间就是日期往后推一天的结果
        return DateUtilsExtJoda.getDateToString(date);
    }

    /**
     * 比较两日期大小
     *
     * @param date      日期
     * @param otherDate 另一个日期
     * @return 比较两日期大小。如果date>otherDate则返回true,否则false
     */
    public static Boolean whenGTOrEQ(Date date, Date otherDate) {
        Boolean flag = false;
        Date dateTmp = DateUtilsExtJoda.getDateTime(date);
        Date otherDateTmp = DateUtilsExtJoda.getDateTime(otherDate);
        if (dateTmp != null && otherDateTmp != null) {
            long time = dateTmp.getTime() - otherDateTmp.getTime();
            if (time >= 0) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 计算得到日期区间的所有日期（包含开始日期）
     * 例如：from=2017-06-25 to=2017-06-28 那么他们之间的日期就是 2017-06-25 2017-06-26 2017-06-27
     *
     * @param from
     * @param to
     * @return
     */
    public static List<Date> computeDateRangeDateEx(Date from, Date to) {
        List<Date> dateRange = new ArrayList<Date>();
        from = DateUtilsExtJoda.getDateFormat(from, DateFormatUtil.DATE_DEFAULT_FORMAT);
        to = DateUtilsExtJoda.getDateFormat(to, DateFormatUtil.DATE_DEFAULT_FORMAT);
        dateRange.add(from);
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(DateUtilsExtJoda.getDateFormat(from, DateFormatUtil.DATE_DEFAULT_FORMAT));
        startCal.add(Calendar.DAY_OF_YEAR, 1);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(DateUtilsExtJoda.getDateFormat(to, DateFormatUtil.DATE_DEFAULT_FORMAT));
        while (startCal.before(endCal)) {
            dateRange.add(startCal.getTime());
            startCal.add(Calendar.DAY_OF_YEAR, 1);
        }
        return dateRange;
    }

    /**
     * 格式化日期 yyyy-MM
     *
     * @param date
     * @return
     */
    public static Date getYearMonth(Date date) {
        return DateUtilsExtJodaT.getDate(new DateTime(date).toString(DateFormatUtil.DATE_YEAR_MONTH_FORMAT));
    }


    //小红点项目 获取开始显示红点的日期
    public static Date getRedSpotDate() {
        Date redSpotDate = DateUtilsExtJodaT.getDate("2018-2-21");
        return redSpotDate;
    }



    /**
     * 获取时间段内固定日期集合
     *
     * @param start
     * @param end
     * @param dayOfMonth
     * @return
     */
    public static List<Date> getFixedDateList(Date start, Date end, int dayOfMonth) {
        List<Date> dateList = new ArrayList<>();
        List<Integer> diff = CalendarUtils.getDiffDates(start, end);
//        int totalMonth = diff.get(0)*12 + diff.get(1) + (diff.get(2) > 0?1:0);
        int totalMonth = diff.get(1);
        //如果目标天小于开始日期的天那么从下月开始
        if (DateUtilsExtJoda.getDay(start) <= dayOfMonth) {
            Date[] dates = computeMonthFirstAndLastDay(DateUtilsExtJoda.getDate(start), 0);
            String dateStr = DateUtilsExtJoda.getDateToString(dates[1]);
            String dayStr = dateStr.substring(dateStr.length() - 2);
            Integer day = Integer.valueOf(dayStr);
            if (dayOfMonth <= day) {
                String computeDate = dateStr.substring(0, dateStr.lastIndexOf("-") + 1);
                Date targetDate = DateUtilsExtJodaT.getDate(computeDate + dayOfMonth);
                dateList.add(targetDate);
            }
        }
        //如果目标天大于结束日期的天那么只计算到结束日期的上个月
        if (DateUtilsExtJoda.getDay(end) < dayOfMonth) {
            totalMonth--;
        }
        String sourceDate = DateUtilsExtJoda.getDateToString(start);
        for (int i = 0; i < totalMonth; i++) {
            sourceDate =DateUtilsExtJodaT.addMonth(sourceDate, 1);
            String computeDate = sourceDate.substring(0, sourceDate.lastIndexOf("-") + 1);
            Date[] dates = computeMonthFirstAndLastDay(DateUtilsExtJodaT.getDate(sourceDate), 0);
            String dateStr = DateUtilsExtJoda.getDateToString(dates[1]);
            String dayStr = dateStr.substring(dateStr.length() - 2);
            Integer day = Integer.valueOf(dayStr);
            if (dayOfMonth <= day) {
                Date targetDate = DateUtilsExtJodaT.getDate(computeDate + dayOfMonth);
                dateList.add(targetDate);
            }
        }
        return dateList;
    }


    /**
     * 获取时间段内固定日期时间集合
     *
     * @param start
     * @param end
     * @param dateTime
     * @return
     */
    public static List<Date> getFixedDateTimeList(Date start, Date end, Date dateTime) {
        List<Date> dateList = new ArrayList<>();
        List<Integer> diff = CalendarUtils.getDiffDates(start, end);
        String datetime = DateUtilsExtJoda.getDateFormatToString(dateTime, DateFormatUtil.DATETIME_DEFAULT_FORMAT);
        int dayOfMonth = Integer.parseInt(datetime.substring(8, 10));
        String hms = datetime.substring(11, 19);
//        int totalMonth = diff.get(0)*12 + diff.get(1) + (diff.get(2) > 0?1:0);
        int totalMonth = diff.get(1);
        //如果目标天小于开始日期的天那么从下月开始
        if (DateUtilsExtJoda.getDay(start) <= dayOfMonth) {
            Date[] dates = computeMonthFirstAndLastDay(DateUtilsExtJoda.getDate(start), 0);
            String dateStr = DateUtilsExtJoda.getDateToString(dates[1]);
            String dayStr = dateStr.substring(dateStr.length() - 2);
            Integer day = Integer.valueOf(dayStr);
            if (dayOfMonth <= day) {
                String computeDate = dateStr.substring(0, dateStr.lastIndexOf("-") + 1);
                computeDate = computeDate + dayOfMonth + " " + hms;
                Date targetDate = DateUtilsExtJodaT.getDate(computeDate);
                dateList.add(targetDate);
            }
        }
        //如果目标天大于结束日期的天那么只计算到结束日期的上个月
        if (DateUtilsExtJoda.getDay(end) < dayOfMonth) {
            totalMonth--;
        }
        String sourceDate = DateUtilsExtJoda.getDateToString(start);
        for (int i = 0; i < totalMonth; i++) {
            sourceDate = DateUtilsExtJodaT.addMonth(sourceDate, 1);
            String computeDate = sourceDate.substring(0, sourceDate.lastIndexOf("-") + 1);
            Date[] dates = computeMonthFirstAndLastDay(DateUtilsExtJodaT.getDate(sourceDate), 0);
            String dateStr = DateUtilsExtJoda.getDateToString(dates[1]);
            String dayStr = dateStr.substring(dateStr.length() - 2);
            Integer day = Integer.valueOf(dayStr);
            if (dayOfMonth <= day) {
                computeDate = computeDate + dayOfMonth + " " + hms;
                Date targetDate = DateUtilsExtJodaT.getDate(computeDate);
                dateList.add(targetDate);
            }
        }
        return dateList;
    }


    /**
     * 开始时间--结束时间拼凑字符串
     *
     * @param start
     * @param end
     * @return
     */
    public static String getStringTime(Date start, Date end) {
        String startTime = DateUtilsExtJoda.getDateFormatToString(start, DateFormatUtil.DATE_DEFAULT_FORMAT);
        String endTime = DateUtilsExtJoda.getDateFormatToString(end, DateFormatUtil.DATE_DEFAULT_FORMAT);
        if (startTime != null && endTime != null) {
            return startTime + "~" + endTime;
        }
        return "暂无~暂无";
    }


    /**
     * @Description: yyyyMMddHHmmss字符串转化为日期
     * @Param: [time]
     * @return: java.util.Date
     * @Author: cx
     * @Date: 2018/5/17
     */
    public static boolean dateEqInMinute(Date date, Date otherDate) {
        String dateStr = DateUtilsExtJoda.getDateFormatToString(date, "yyyyMMddHHmm");
        String otherDateStr = DateUtilsExtJoda.getDateFormatToString(otherDate, "yyyyMMddHHmm");
        if (dateStr != null && otherDateStr != null) {
            return dateStr.equals(otherDateStr);
        }
        return false;
    }


}
